/**
 * Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 *
 * For the applicable distribution terms see the license.txt -file, included in
 * the distribution.
 */

#ifndef DECLARATIVEPURCHASELISTMODEL_H
#define DECLARATIVEPURCHASELISTMODEL_H

#include <QAbstractListModel>
#include <QDeclarativeParserStatus>
#include <iapclient.h>

class PurchasableItemBase;

/*!
  \class DeclarativePurchaseListModel
  \brief Implements catalog list model.
*/
class DeclarativePurchaseListModel : public QAbstractListModel,
                                     public QDeclarativeParserStatus
{
    Q_OBJECT
    Q_INTERFACES(QDeclarativeParserStatus)

friend class ProductCatalogModel;

public: // From QAbstractListModel
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role) const;
    bool setData (const QModelIndex &index,
                    const QVariant &value, int role = Qt::EditRole);

public:
    Q_DISABLE_COPY(DeclarativePurchaseListModel)
    /*!
      Constructor
    */
    explicit DeclarativePurchaseListModel(QObject *parent = 0);
    /*!
      Destructor
    */
    ~DeclarativePurchaseListModel();

public:
    //QDeclarativeParserStatus interface
    /*!
      empty implementation of the base class virtual method
    */
    void classBegin(){}
    /*!
      empty implementation of the base class virtual method
    */
    void componentComplete(){}
public:
    // for model items to use only
    /*!
      Switches the model to update mode
    */
    void beginModelUpdate();
    /*!
      Commits updates in the model
    */
    void commitModelUpdate();
    /*!
      Getters for In-application API client
     */
    IAPClient &client();
    /*!
      Callback function on Purchase Flow Finished event
     */
    void purchaseFlowFinished(bool statusSuccess);

public:
    // utility function
    /*!
      Searches the model for a product ID
      and returns product data
    */
    PurchasableItemBase *find(QString productID) const;

signals:
    /*!
      The signal supports ProductCatalogModel::isApplicationBusy property notification
    */
    void applicationBusyChanged();

    /*!
      Signals towards Filter and Sorting Proxy model
    */
    void modelUpdated();

    /*!
      signals towards Filter and Sorting Proxy model
    */
    void purchaseCompleted(bool status);

protected slots:
    // In-Application Purchase specific slots
    /*!
      Handles the signal when the request for products available for
      restoration is complete.
    */
    void restorableProductsReceived(int requestId, QString status,
                                                    IAPClient::ProductDataList items);
    /*!
      Handles the signal when the user and device data request is completed.
    */
    void userAndDeviceDataReceived(int requestId, QString status,
                                    IAPClient::UserAndDeviceDataHash userdata);

private:
    //utility functions
    /*!
      Reads product catalog
    */
    void readDRMCatalog();
    /*!
      Getter to obtain product data by index
    */
    PurchasableItemBase *record(int index) const;
    /*!
      Getter to obtain product data by virtual index
      virtual index supports the model sorting and filtering
      additional info please see in ProductCatalogModel class implementation
      As parameter accepts product virtual index seen by QML
    */
    PurchasableItemBase *record(const QModelIndex &index) const;
    /*!
      Buy product request
      As parameter accepts product virtual index seen by QML
    */
    void buy(const QModelIndex &index);
    /*!
      Restore product request
    */
    void restoreProducts();
    /*!
      Get user info request
    */
    void getUserInfo();

    /*!
      this trigger is to prevent list flickering during first time built
      \returns whether model redrawing is possible on QML side
    */
    bool allowModelUpdateNotifications();

    /*!
      This is a support for the following requirement:

       "Once you have bought the both items, the title �Items to buy� should be visible there,
       but under it saying �No items�. "

      This is a pseudo-record in the model that results in QML ListView "No items" row
      There is no other work around found in QML ListView to have dynamic rows like supported
      "header" and "section". QML ListView re-implementation was considered too heavy for
      having "No items" mark
      Parameter "role" is the model data interface, see QAbstractListModel::data(int role)
      for details
    */
    QVariant noitemsMark(int role) const;

private:
    // In-Application Purchase API
    IAPClient                       m_client;

    //for aggregate query to product list getRestorableProducts()
    int                             m_requestId;

    // the model data
    QList<PurchasableItemBase*>     m_data;
    // the model reference counter to support commit group operation
    int                             m_modelCommitRefCounter;

    // enables the whole application busy indicator
    bool                            m_isApplicationBusy;
};

#endif // DECLARATIVEPURCHASELISTMODEL_H
